package metro.system;

import mycollections.list.MyCollections;
import mycollections.list.MyLinkedList;
import metro.cards.*;
import metro.cards.types.CardSpecialType;
import metro.cards.types.CardType;
import metro.response.Response;
import metro.tourniquet.Tourniquet;

import java.util.Calendar;
import java.util.TreeSet;

public class MetroSystem {
    private final int cost;
    private TreeSet<Card> cards;
    private MyLinkedList<Response> history;
    public MetroSystem() {
        history=new MyLinkedList<>();
        cards=new TreeSet<>();
        cost=2*100;
    }

    public Response pass(Tourniquet tourniquet,long cardId) {
        Card c=find(cardId);
        Response response;
        if (c==null)
            response= Response.createNegativeCardNotFound(null,tourniquet);
        else
            response = c.use(this,tourniquet);
        history.add(response);
        return response;
    }

    public int getCost() {
        return cost;
    }

    public Card addCard(CardKind kind){
        Card card;
        switch (kind){
            case DURATION_MONTH:
                card=DurationCard.createMonthCard(getCurrentDate());
                break;
            case DURATION_NEXT_MONTH:
                card= DurationCard.createNextMonthCard(getCurrentDate());
                break;
            case ENTRANCE_10:
                card= EntranceCard.createTenEntranceCard(getCurrentDate());
                break;
            case ENTRANCE_20:
                card= EntranceCard.createTwentyEntranceCard(getCurrentDate());
                break;
            case MONEY_0:
                card= MoneyCard.createEmptyDollarsCard(getCurrentDate());
                break;
            case MONEY_50:
                card= MoneyCard.createFiftyDollarsCard(getCurrentDate());
                break;
            case MONEY_100:
                card= MoneyCard.createHundredDollarsCard(getCurrentDate());
                break;
            case STUDENT:
                card= StudentCard.createStudentCard(getCurrentDate());
                break;
            default:
                card= null;
        }
        if (card!=null)
            cards.add(card);
        return card;
    }

    private Card find(long cardId){
        for (Card c:cards)
            if (c.getId()==cardId)
                return c;
        return null;
    }

    public Calendar getCurrentDate(){
        return Calendar.getInstance();
    }

    public MyLinkedList<Response> getHistory(){
        MyLinkedList<Response> copy=new MyLinkedList<>();
        MyCollections.copy(copy,history);
        return copy;
    }

    public MyLinkedList<Response> getHistory(CardType type){
        MyLinkedList<Response> copy=new MyLinkedList<>();
        for (Response r:history)
            if (r.getCardType()==type && r.getCardSpecialType()==CardSpecialType.COMMON)
                copy.add(r);
        return copy;
    }

    public MyLinkedList<Response> getHistory(CardSpecialType type){
        MyLinkedList<Response> copy=new MyLinkedList<>();
        for (Response r:history)
            if (r.getCardSpecialType()==type)
                copy.add(r);
        return copy;
    }

}
